package com.dxysun.sentinel.springboot.config;

import javax.annotation.PostConstruct;
import javax.servlet.Filter;

import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
import com.alibaba.csp.sentinel.datasource.apollo.ApolloDataSource;
import com.alibaba.csp.sentinel.property.SentinelProperty;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter;
import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager;

import java.util.List;

@Configuration
public class WebConfig
{
	@PostConstruct
	public void init() throws Exception
	{
		WebCallbackManager.setRequestOriginParser((request) -> {
			System.out.println("from addr:" + request.getRemoteAddr());
			System.out.println("from url:" + request.getRequestURI());
			return request.getRequestURI() + request.getRemoteHost();
		});
		WebCallbackManager.setUrlBlockHandler((request, response, exception) -> {
			response.getWriter().print("blocked");
		});
		//		WebServletConfig.setBlockPage(blockPage);

		// namespaceName 对应 Apollo 的命名空间名称
		// ruleKey 对应规则存储的 key
		// defaultRules 对应连接不上 Apollo 时的默认规则
		String namespaceName = "Hello";
		String ruleKey = "ruleKey";
		String defaultRules = "[{\"resource\" : \"/hello\",\"count\":20}]";
		ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new ApolloDataSource<>(namespaceName, ruleKey,
				defaultRules, source -> {
					System.out.println("readSource:" + source);
					return JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
					});
				});
		SentinelProperty<List<FlowRule>> sentinelProperty = flowRuleDataSource.getProperty();
		System.out.println("FlowRule:" + JSON.toJSONString(flowRuleDataSource.loadConfig()));
		FlowRuleManager.register2Property(sentinelProperty);
	}

	@Bean
	public FilterRegistrationBean sentinelFilterRegistration()
	{
		FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
		registration.setFilter(new CommonFilter());
		registration.addUrlPatterns("/*");
		registration.setName("sentinelFilter");
		registration.setOrder(1);
		return registration;
	}
}
